from ..errors import CardGameError, UnimplementedError
from ..errors import NoSuchUserError, NoSuchCardError, NoSuchCollectionError

import sys

class PermissionsError(CardGameError):
    """
    Parent class for all errors in this module.
    """
    pass

class NoSuchPermissionsError(PermissionsError):
    """
    Generated when a PermissionsController is asked 
    about a type of permission that does not exist.
    """
    pass

class PermissionsController(object):
    """
    A handler framework for confirming whether an 
    in-game action is permitted by a specified user.
    
    Subclass this with your specific permission implementation 
    (e.g., a SQL database).
    """
    
    def __init__(self, args):
        self.args = args    ## The form of the 'args' is left unspecified
        
    def allowed(self, user, action, params):
        """
        Takes a user ID, an action name, and parameters
        Returns 'True' if the user can perform the action or
        'False' if they cannot.
        """
        raise UnimplementedError(self)

class AllowAllController(PermissionsController):
    """
    All permission requests are allowed.  Provided 
    for testing purposes only.
    """
    
    def allowed(self, user, action, params): return True

class DenyAllController(PermissionsController):
    """
    All permission requests are denied.  Provided 
    for testing purposes only.
    """
    
    def allowed(self, user, action, params): return False
    
class InMemoryController(PermissionsController):
    """
    Permission based on an in-memory table.  Provided 
    for testing purposes only.
    """
    
    def __init__(self, args):
        """
        Takes a dictionary pairing user IDS to dictionaries of 
        permission types paired to whether they are allowed or 
        not.
        """
        self.permissions = args
        
    def allowed(self, user, action, params):
        """
        Takes a user ID, an action name, and a 
        list of condition-specifying parameters.
        """
        if (self.permissions.has_key(user)):
            if (self.permissions[user].has_key(action)):
                return self.permissions[user][action]
            else:
                raise NoSuchPermissionsError(action)
        else:
            raise NoSuchUserError(user)